"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuildAction = void 0;
const chalk_1 = require("chalk");
const inquirer = require("inquirer");
const fs = require("fs-extra");
const path = require("path");
// import { AssetsManager } from '../lib/compiler/assets-manager';
// import { Compiler } from '../lib/compiler/compiler';
// import { getValueOrDefault } from '../lib/compiler/helpers/get-value-or-default';
// import { TsConfigProvider } from '../lib/compiler/helpers/tsconfig-provider';
// import { PluginsLoader } from '../lib/compiler/plugins-loader';
// import { WatchCompiler } from '../lib/compiler/watch-compiler';
// import { WebpackCompiler } from '../lib/compiler/webpack-compiler';
// import { WorkspaceUtils } from '../lib/compiler/workspace-utils';
// import {
//   ConfigurationLoader,
//   NestConfigurationLoader,
// } from '../lib/configuration';
// import { defaultOutDir } from '../lib/configuration/defaults';
// import { FileSystemReader } from '../lib/readers';
const ui_1 = require("../lib/ui");
const abstract_action_1 = require("./abstract.action");
// import buildDllScript from 'cpaas-webpack-scripts/scripts/build-dll';
const build_1 = require("cpaas-webpack-scripts/scripts/build");
// const transpileScript = require( 'cpaas-webpack-scripts/scripts/transpile').default;
class BuildAction extends abstract_action_1.AbstractAction {
    handle(inputs, options) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield this.runBuild(inputs, options); // inputs [] options [{name, value}]
            }
            catch (err) {
                if (err instanceof Error) {
                    console.log(`\n${ui_1.ERROR_PREFIX} ${err.message}\n`);
                    console.error(err);
                }
                else {
                    console.error(`\n${chalk_1.default.red(err)}\n`);
                    console.error(err);
                }
                process.exit(1);
            }
        });
    }
    runBuild(inputs, options) {
        return __awaiter(this, void 0, void 0, function* () {
            const allPackages = options.find((i) => i.name === 'allPackages')
                .value; // 是否所有packages
            const nonInteractive = options.find((option) => option.name === 'nonInteractive').value;
            const buildDllDev = options.find((i) => i.name === 'buildDllDev')
                .value;
            const buildDll = buildDllDev ||
                options.find((i) => i.name === 'buildDll').value;
            const onlyBuildParent = options.find((i) => i.name === 'onlyBuildParent')
                .value; // 只 build 父模块
            // const buildMicroWithoutParent = options.find(
            //   (i) => i.name === 'buildMicroWithoutParent'
            // )!.value as boolean; // 只编译子模块 不编译父模块
            const concurrentBuildNumber = options.find((i) => i.name === 'concurrentBuildNumber').value;
            if (!allPackages && !nonInteractive && !buildDll && !onlyBuildParent) {
                yield askForMissingInformation(options);
            } // 未指定打包模块 则选择打包模块  并修改 options 里 packages 的 value 为 所选择的要打包模块
            const packages = getPackagesOptions(options).value;
            yield build_1.default({
                concurrentBuildNumber: concurrentBuildNumber
                    ? Number(concurrentBuildNumber)
                    : 0,
                buildDll,
                buildDllDev,
                onlyBuildMicro: options.find((i) => i.name === 'onlyBuildMicro')
                    .value,
                onlyBuildParent,
                packages: packages
                    ? typeof packages === 'string'
                        ? packages.split(',')
                        : packages
                    : undefined,
            });
        });
    }
}
exports.BuildAction = BuildAction;
const askForMissingInformation = (options) => __awaiter(void 0, void 0, void 0, function* () {
    const nameInput = getPackagesOptions(options); // 获取 options 里所有 要打包的packages模块
    if (!nameInput.value) {
        const prompt = inquirer.createPromptModule();
        const message = '请选择子模块?';
        const buildPackageNames = getMicroPackages(); // 获取 .cpaasrc.js 里的packages所有目录
        if (buildPackageNames.length > 1) {
            const questions = [
                generateSelect('packages')(message)(buildPackageNames),
            ];
            const answers = yield prompt(questions);
            replaceInputMissingInformation(options, answers); // 修改 options packages value 为 所选择的要打包模块
        }
    }
});
const getMicroPackages = () => {
    const paths = require('cpaas-webpack-scripts/config/paths');
    // 如果 cwd 是子模块的目录，就只编译当前模块.
    if (paths.appRootPath !== paths.appPath) {
        return [fs.readJSONSync(path.resolve(paths.appPath, 'package.json')).name];
    }
    let buildPackageNames = [];
    const cpaasRootConfig = paths.getCpaasConfig(paths.appPath);
    if (cpaasRootConfig && cpaasRootConfig.packages) {
        buildPackageNames = cpaasRootConfig.packages
            .filter((item) => !item.external)
            .map((item) => item.name);
    }
    return buildPackageNames;
};
const getPackagesOptions = (inputs) => inputs.find((input) => input.name === 'packages');
const generateSelect = (name) => {
    return (message) => {
        return (choices) => ({
            type: 'checkbox',
            name,
            message,
            choices,
        });
    };
};
const replaceInputMissingInformation = (inputs, answers) => {
    return inputs.map((input) => (input.value =
        input.value !== undefined ? input.value : answers[input.name]));
};
